package cn.jisol.ngame.demo.network.netty.udp.game;

import cn.jisol.ngame.actions.frame.SNFrameSyncAction;
import cn.jisol.ngame.actions.frame.client.NFrameSyncClient;
import cn.jisol.ngame.demo.client.UnityFrameNClient;
import cn.jisol.ngame.demo.client.UnityNClient;
import cn.jisol.ngame.demo.game.action.unity.service.SNUnityFrameAction;
import cn.jisol.ngame.demo.network.netty.udp.decoders.DefaultProtoBufDecoder;
import cn.jisol.ngame.demo.network.netty.udp.encoders.DefaultProtoBufEncoder;
import cn.jisol.ngame.netty.annotation.AJNetty;
import cn.jisol.ngame.netty.annotation.control.*;
import cn.jisol.ngame.netty.network.UDPJNettyNetwork;
import cn.jisol.ngame.netty.network.udp.session.UDPSession;
import cn.jisol.ngame.netty.network.udp.session.UDPSessionGroup;
import cn.jisol.ngame.network.websocket.WebFrameSyncSocket;
import cn.jisol.ngame.proto.message.NGameMessageOuterClass;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 启动Netty UDP
 *
 * Unity 帧同步的测试类
 *
 */
@AJNetty(
        port = 1001,
        network = UDPJNettyNetwork.class,
        decoders = {
                DefaultProtoBufDecoder.class
        },
        encoders = {
                DefaultProtoBufEncoder.class
        }
)
@Component
public class UnityFrameUDPServer {


        @Autowired
        SNFrameSyncAction server;

        //客户端列表
        public final Map<String, NFrameSyncClient> CLIENTS = new ConcurrentHashMap<>();

        /**
         * 初始化开始 - 用于修改Network信息
         */
        @JNInit
        public void initNetwork(UDPJNettyNetwork network){


                //因UDP协议无法监听客户端是否在线 所以导致 onClose失效 这里需要吧心跳开启
                network.setOpenAlive(true);
                network.setVAliveTime(1000);
                network.setVAliveError(1000);


        }

        /**
         * 初始化成功
         */
        @JNInitSuccess
        public void initNetworkSuccess(UDPJNettyNetwork network){

                String sid = network.getSid();
                server.clients = this.CLIENTS;

        }

        @JNOpen
        public void onOpen(UDPSession session, UDPSessionGroup clients){

                //将session添加到Clients中
                CLIENTS.put(session.getCId(),new UnityFrameNClient(session));
                System.out.println(String.format("【%s】连接服务器 - 当前服务器在线人数:%s",session.getCId(),clients.size()));

        }

        @JNMessage
        public void onMessage(UDPSession session, UDPSessionGroup clients, NGameMessageOuterClass.NGameMessage message, String text){

                //查询clients中的client
                UnityFrameNClient client = null;
                if(Objects.isNull(client = this.getClient(session.getCId()))) this.onOpen(session,clients);

                //统一发送到客户端的onMessage中
                client.onMessage(message);

        }

        @JNClose
        public void onClose(UDPSession session,UDPSessionGroup clients){

                //移除Client
                CLIENTS.remove(session.getCId());
                System.out.println(String.format("【%s】离开服务器 - 当前服务器在线人数:%s",session.getCId(),clients.size()));

                //如果没有玩家则关闭帧同步
                if(CLIENTS.size() == 0){
                        this.server.nGameSyncEnd();
                }

        }

        public UnityFrameNClient getClient(String cId){
                return (UnityFrameNClient)CLIENTS.get(cId);
        }


}
